package gemini.castor.ui.client.page.widget.address;

import gemini.basic.model.Address;
import gemini.castor.ui.client.page.widget.NumberFieldStandard;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import com.google.gwt.core.client.GWT;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiTemplate;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.Panel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.validation.client.InvalidConstraint;
import com.google.gwt.validation.client.interfaces.IValidator;

public class AddressWidget extends Composite {

	@UiTemplate("AddressWidget.ui.xml")
	interface MyUiBinder extends UiBinder<Panel, AddressWidget> {
	}

	private static final MyUiBinder binder = GWT.create(MyUiBinder.class);

	private IValidator<AddressObject> validator;
	private AddressObject object;
	
	public void setAddressObject(AddressObject object) {
		this.object = object;
	}

	public AddressWidget() {
		initWidget(binder.createAndBindUi(this));
		validator = GWT.create(AddressObject.class);
		initData();
	}

	private void initData() {
		cities = new ArrayList<String>();
		cities.add("Ho Chi Minh");
		cities.add("Ha Noi");
		
		for (String city : cities) {
			lbxCity.addItem(city);
		}
		
		countries = new ArrayList<String>();
		countries.add("Viet Nam");
		
		for (String country : countries) {
			lbxCountry.addItem(country);
		}
	}

	@UiField
	TextBox tbxLine1;

	@UiField
	TextBox tbxLine2;

	@UiField
	TextBox tbxDistrict;
	
	@UiField
	NumberFieldStandard tbxZipCode;
	
	@UiField
	ListBox lbxCity;
	
	@UiField
	ListBox lbxCountry;
	
	List<String> cities;

	List<String> countries;
	
	public boolean isValidate(){
		resetStyle();
		bind();
		boolean result = true;
		Set<InvalidConstraint<AddressObject>> invalidConstraints = validator.validate(object);
		Iterator<InvalidConstraint<AddressObject>> it = invalidConstraints
			.iterator();
		
		while (it.hasNext()) {
			if(result){
				result = false;
			}
			InvalidConstraint<AddressObject> ic = it.next();
			showError(ic.getItemName(), ic.getMessage());
		}
		
		return result;
	}
	
	private void showError(String widgetName, String errorString) {
		if (widgetName.equals("line1")) {
			tbxLine1.addStyleDependentName("error");
		} else if (widgetName.equals("district")) {
			tbxDistrict.addStyleDependentName("error");
		}	
	}
	
	public void bind(){
		object.setCity(lbxCity.getValue(lbxCity.getSelectedIndex()));
		object.setCountry(lbxCountry.getValue(lbxCountry.getSelectedIndex()));
		object.setDistrict(tbxDistrict.getValue());
		object.setLine1(tbxLine1.getValue());
		object.setLine2(tbxLine2.getValue());
		object.setZipCode(tbxZipCode.getValue());
	}
	
	public void reset(){
		resetValue();
		resetStyle();
	}
	
	private void resetValue() {
		tbxLine1.setValue("", true);
		tbxDistrict.setValue("", true);
		tbxLine2.setValue("", true);
		tbxZipCode.setValue("", true);
		lbxCity.setSelectedIndex(0);
		lbxCountry.setSelectedIndex(0);
	}
	
	private void resetStyle(){
		tbxLine1.removeStyleDependentName("error");
		tbxDistrict.removeStyleDependentName("error");
	}
	
	public void setAddress(Address address){
		tbxLine1.setValue(address.getAddressLine1(), true);
		tbxDistrict.setValue(address.getDistrict(), true);
		tbxLine2.setValue(address.getAddressLine2(), true);
		tbxZipCode.setValue("", true);
		lbxCity.setSelectedIndex(0);
		lbxCountry.setSelectedIndex(0);
	}
	
}
